package com.zhouyu;

import com.zhouyu.advice.ZhouyuAroundAdvice;
import com.zhouyu.advice.ZhouyuBeforeAdvice;
import com.zhouyu.service.OrderService;
import com.zhouyu.service.UserService;
import com.zhouyu.service.UserServiceInterface;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

import java.lang.reflect.Method;

/**
 * @author leimingchao
 * create 2025-05-15 22:14
 */
public class TestProxyFactory {

	public static void main(String[] args) {

		UserService target = new UserService();

		ProxyFactory proxyFactory = new ProxyFactory();
		//target:被代理对象
		proxyFactory.setTarget(target);
		//MethodInterceptor.invoke(invocation)---->before--->invocation
		//proxyFactory.addAdvice(new ZhouyuBeforeAdvice());
		//MethodInterceptor.invoke(invocation)
		//proxyFactory.addAdvice(new ZhouyuAroundAdvice());

		//proxyFactory.setExposeProxy(true);

		proxyFactory.addAdvice(new MethodInterceptor() {
			@Nullable
			@Override
			public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
				System.out.println("before...");
				Object result = invocation.proceed();
				System.out.println("after...");
				return result;
			}
		});

		//Advisor = Pointcut(定义代理逻辑应用到哪个方法上) + Advice(代理逻辑)
		proxyFactory.addAdvisor(new PointcutAdvisor() {
			@Override
			public Pointcut getPointcut() {
				return new StaticMethodMatcherPointcut() {
					/**
					 * @param method the candidate method 候选方法
					 * @param targetClass the target class 被代理的目标类
					 * @return
					 */
					@Override
					public boolean matches(Method method, Class<?> targetClass) {
						//return "test".equals(method.getName());
						return targetClass.equals(OrderService.class);
					}
				};
			}

			@Override
			public Advice getAdvice() {
				return new ZhouyuBeforeAdvice();
			}

			@Override
			public boolean isPerInstance() {
				return false;
			}
		});

		UserService proxy = (UserService) proxyFactory.getProxy();

		//代理对象执行方法时，会首先去执行Pointcut的match方法，匹配了才会执行Advice的代理逻辑
		//proxy.a();
		proxy.test();
	}
}
